package com.hsgene.order.service.impl;

import com.hsgene.common.util.date.SimpleDateUtils;
import com.hsgene.common.util.result.ApiResult;
import com.hsgene.common.util.result.NullObject;
import com.hsgene.common.util.support.Pagination;
import com.hsgene.common.util.validation.FieldChecker;
import com.hsgene.goods.dto.GoodsOriginDto;
import com.hsgene.goods.dto.specification.GoodsSpecificationDto;
import com.hsgene.logistics.domain.LogisticsInfo;
import com.hsgene.logistics.dto.KuaiDi100DeatisInfo;
import com.hsgene.order.condition.OrderSupplierCondition;
import com.hsgene.order.constants.OrderSupplierStatus;
import com.hsgene.order.constants.SuppliOrConsoleType;
import com.hsgene.order.domain.OrderSupplier;
import com.hsgene.order.dto.OrderSupplierDto;
import com.hsgene.order.dto.OrderSupplierInvoiceDto;
import com.hsgene.order.exception.OrderErrorCode;
import com.hsgene.order.persistence.OrderSupplierRepository;
import com.hsgene.order.service.OrderSupplierService;
import com.hsgene.order.service.api.GeneratorService;
import com.hsgene.order.service.api.GoodsOriginService;
import com.hsgene.order.service.api.LogisticsService;
import com.hsgene.order.service.api.SupplierDetectionService;
import com.hsgene.supplier.domain.DetectionOrganization;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 机构订单ServiceImpl
 *
 * @author wangbing
 * @version 1.0, 2018/8/3
 */
@Service
public class OrderSupplierServiceImpl implements OrderSupplierService {
    @Resource
    private OrderSupplierRepository orderSupplierRepository;
    @Resource
    private GoodsOriginService goodsService;
    @Resource
    private SupplierDetectionService supplierDetectionService;
    @Resource
    private LogisticsService logisticsService;
    @Resource
    private GeneratorService generatorService;

    @Override
    public ApiResult<Pagination<OrderSupplierDto>> queryOrderSupplier(OrderSupplierCondition condition, SuppliOrConsoleType console) {

        int totalCount = orderSupplierRepository.queryOrderSupplierCount(condition);
        Pagination<OrderSupplierDto> pagination = Pagination.newInstance(condition.getLimitHelper(), totalCount);
        if (totalCount > 0) {
            List<OrderSupplier> orderSupplier = orderSupplierRepository.queryOrderSupplier(condition);
            if (!CollectionUtils.isEmpty(orderSupplier)) {
                List<OrderSupplierDto> dtos = orderSupplier.stream().map(e -> {
                    OrderSupplierDto orderSupplierDto = new OrderSupplierDto();
                    BeanUtils.copyProperties(e, orderSupplierDto);
                    ApiResult<GoodsOriginDto> goods = goodsService.getGoods(e.getGoodsOriginId());
                    Short detectionDuration = goods.getData().getDetectionDuration();
                    orderSupplierDto.setDetectionDuration(detectionDuration);
                    ApiResult<DetectionOrganization> organization = supplierDetectionService.findOrganization(e.getSupplierId());
                    orderSupplierDto.setSupplierName(organization.getData().getSupplierName());
                    OrderSupplierStatus anEnum = OrderSupplierStatus.getEnum(e.getStatus());
                    if (console.equals(SuppliOrConsoleType.CONSOLE)) {
                        orderSupplierDto.setStatusDesc(anEnum.getDesc());
                    } else {
                        orderSupplierDto.setStatusDesc(anEnum.getDescSupplie());
                    }
                    orderSupplierDto.setInvoiceTypeDesc(OrderSupplierStatus.getEnum(e.getInvoiceType()).getDesc());
                    return orderSupplierDto;
                }).collect(Collectors.toList());
                pagination.setResult(dtos);
            }
        } else {
            pagination.setResult(new ArrayList<>());
        }
        return ApiResult.succ(pagination);
    }

    @Override
    public ApiResult<OrderSupplierDto> getById(String id, SuppliOrConsoleType console) {
        OrderSupplier orderSupplier = orderSupplierRepository.getById(id);
        if (orderSupplier == null) {
            return ApiResult.fail(OrderErrorCode.ORDER_NOT_EXISTED);
        }
        OrderSupplierDto orderSupplierDto = new OrderSupplierDto();
        BeanUtils.copyProperties(orderSupplier, orderSupplierDto);
        OrderSupplierStatus anEnum = OrderSupplierStatus.getEnum(orderSupplier.getStatus());
        orderSupplierDto.setStatusDesc(anEnum.getDesc());
        orderSupplierDto.setInvoiceTypeDesc(OrderSupplierStatus.getEnum(orderSupplier.getInvoiceType()).getDesc());
        //商品信息
        ApiResult<GoodsOriginDto> goods = goodsService.getGoods(orderSupplier.getGoodsOriginId());
        GoodsOriginDto goodsData = goods.getData();
        orderSupplierDto.setGoodsOriginName(goodsData.getGoodsName());
        if (!CollectionUtils.isEmpty(goodsData.getSpecification())) {
            String specification = "";
            for (GoodsSpecificationDto goodsSpecificationDto : goodsData.getSpecification()) {
                specification = specification + goodsSpecificationDto.getName() + " * " + goodsSpecificationDto.getCount() + ";";
            }
            orderSupplierDto.setSpecification(specification);
        }

        //检测机构
        ApiResult<DetectionOrganization> organization = supplierDetectionService.findOrganization(orderSupplier.getSupplierId());
        orderSupplierDto.setSupplierName(organization.getData().getSupplierName());
        //物流信息
        ApiResult<List<LogisticsInfo>> listApiResult = logisticsService.queryLogistics(orderSupplier.getSampleExpressageNo());
        List<KuaiDi100DeatisInfo> kuaiDi100DeatisInfos = getKuaiDi100DeatisInfos(listApiResult);
        orderSupplierDto.setKuaiDi100DeatisInfos(kuaiDi100DeatisInfos);
        //报告物流
        //if (console.equals(SuppliOrConsoleType.SUPPLIE)) {
        ApiResult<List<LogisticsInfo>> listApiResult1 = logisticsService.queryLogistics(orderSupplier.getReportExpressageNo());
        List<KuaiDi100DeatisInfo> kuaiDi100DeatisInfos1 = getKuaiDi100DeatisInfos(listApiResult1);
        orderSupplierDto.setKuaiDi100DeatisInfosSupplie(kuaiDi100DeatisInfos1);
        // }
        return ApiResult.succ(orderSupplierDto);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult<NullObject> updateStatus(String id, String type) {
        FieldChecker.checkEmpty(id, "orderSupplierId");
        OrderSupplier byId = orderSupplierRepository.getById(id);
        if (byId == null) {
            return ApiResult.fail(OrderErrorCode.ORDER_NOT_EXISTED);
        }
        OrderSupplier orderSupplier = new OrderSupplier();
        orderSupplier.setId(id);
        //确认收货
        if (type.equals(SuppliOrConsoleType.CONSOLE.getCode())) {
            orderSupplier.setStatus(OrderSupplierStatus.CONFIRMED_REPORT.getCode());
        }
        //确认收样
        if (type.equals(SuppliOrConsoleType.SUPPLIE.getCode())) {
            orderSupplier.setStatus(OrderSupplierStatus.CONFIRMED_SAMPLE.getCode());
        }
        int i = orderSupplierRepository.updateStatus(orderSupplier);
        return ApiResult.succ();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult<NullObject> insertInvoice(OrderSupplierInvoiceDto orderSupplierInvoiceDto) {
        orderSupplierInvoiceDto.setCreateTime(new Date());
        int i = orderSupplierRepository.insertInvoice(orderSupplierInvoiceDto);
        String[] split = orderSupplierInvoiceDto.getRelationOrderIds().split(",");
        Map<String, Object> map = new HashMap<>();
        map.put("ids", split);
        map.put("id", orderSupplierInvoiceDto.getId());
        orderSupplierRepository.insertOrderRelayIds(map);
        return ApiResult.succ();
    }

    @Override
    public ApiResult<OrderSupplierInvoiceDto> getInvoice(String id) {
        if (StringUtils.isEmpty(id)) {
            return ApiResult.fail(OrderErrorCode.PRIMARY_KEY_NOT_EXISTED);
        }
        OrderSupplier byId = orderSupplierRepository.getById(id);
        OrderSupplierInvoiceDto orderSupplierInvoiceDto = orderSupplierRepository.getInvoiceByPermaryKey(byId.getInvoiceId());
        return ApiResult.succ(orderSupplierInvoiceDto);
    }

    @Override
    public ApiResult getInvoices(String ids) {
        if (StringUtils.isEmpty(ids)) {
            return ApiResult.fail(OrderErrorCode.PRIMARY_KEY_NOT_EXISTED);
        }
        String[] split = ids.split(",");
        List<String> list = new ArrayList<>();
        for (String id : split) {
            OrderSupplier byId = orderSupplierRepository.getById(id);
            if (byId.getInvoiceId() != null) {
                list.add(byId.getItemOrderId());
            }
        }
        if (list != null && list.size() > 0) {
            return new ApiResult(230030, "already_exists", "已经存在该发票", list);
        }
        return ApiResult.succ();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ApiResult insertSample(LogisticsInfo logisticsInfo) {
        ApiResult apiResult = logisticsService.addLogistics(logisticsInfo);
        if (apiResult.getCode() == 200) {
            OrderSupplier orderSupplier = new OrderSupplier();
            orderSupplier.setId(logisticsInfo.getId());
            orderSupplier.setStatus(OrderSupplierStatus.SAMPLE_DELIVERED.getCode());
            orderSupplierRepository.updateStatus(orderSupplier);
        }
        return apiResult;
    }

    @Override
    public ApiResult<NullObject> updateReportSupplie(OrderSupplier orderSupplier) {
        if (StringUtils.isEmpty(orderSupplier.getdetecionReport())) {
            return ApiResult.fail(OrderErrorCode.OPERATION_FAILED);
        }
        int i = orderSupplierRepository.updateReportSupplie(orderSupplier);
        if (i > 0) {
            return ApiResult.succ();
        }
        return ApiResult.fail(OrderErrorCode.OPERATION_FAILED);
    }

    private List<KuaiDi100DeatisInfo> getKuaiDi100DeatisInfos(ApiResult<List<LogisticsInfo>> apiResult) {
        List<KuaiDi100DeatisInfo> kuaiDi100DeatisInfos = new LinkedList<>();
        List<LogisticsInfo> logisticsInfos = apiResult.getData();
        logisticsInfos.stream().forEach(logisticsInfo -> {
            KuaiDi100DeatisInfo kuaiDi100DeatisInfo = new KuaiDi100DeatisInfo();
            kuaiDi100DeatisInfo.setContext(logisticsInfo.getLogisticsTrackingDescription());
            String time = SimpleDateUtils.dateFormatToStr(logisticsInfo.getLogisticsTrackingTime());
            kuaiDi100DeatisInfo.setTime(time);
            kuaiDi100DeatisInfo.setFtime(time);
            kuaiDi100DeatisInfos.add(kuaiDi100DeatisInfo);
        });
        return kuaiDi100DeatisInfos;
    }
}
